#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
福特配置器数据完整性验证
验证抓取数据的完整性、准确性和一致性
"""

import sys
import os
import json
import re
sys.path.append('.')

from src.car_series import CarSeries
from src.car_object import CarObject
from src.car_extras import CarExtras


class DataIntegrityValidator:
    """数据完整性验证器"""
    
    def __init__(self):
        self.validation_results = {}
        self.issues_found = []
    
    def validate_output_file(self, file_path):
        """
        验证输出文件的完整性
        
        Args:
            file_path: 输出文件路径
            
        Returns:
            bool: 验证是否通过
        """
        print(f"📁 验证输出文件: {file_path}")
        
        if not os.path.exists(file_path):
            self.add_issue("文件不存在", f"输出文件 {file_path} 不存在")
            return False
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            print("  ✓ 文件格式正确，可以解析为JSON")
            
            # 验证顶级结构
            if not self.validate_top_level_structure(data):
                return False
            
            # 验证车系信息
            if not self.validate_car_series_info(data):
                return False
            
            # 验证车型数据
            if not self.validate_car_objects(data.get('car_objects', [])):
                return False
            
            return True
            
        except json.JSONDecodeError as e:
            self.add_issue("JSON格式错误", f"无法解析JSON: {e}")
            return False
        except Exception as e:
            self.add_issue("文件读取错误", f"读取文件时出错: {e}")
            return False
    
    def validate_top_level_structure(self, data):
        """验证顶级数据结构"""
        print("  🔍 验证顶级数据结构...")
        
        required_fields = ['car_series_name', 'car_objects']
        optional_fields = ['catalog_id', 'series_code', 'default_paint']
        
        # 检查必需字段
        for field in required_fields:
            if field not in data:
                self.add_issue("缺失必需字段", f"顶级结构缺少必需字段: {field}")
                return False
            
            if not data[field]:
                self.add_issue("字段为空", f"必需字段 {field} 为空")
                return False
        
        # 检查数据类型
        if not isinstance(data['car_series_name'], str):
            self.add_issue("字段类型错误", "car_series_name 必须是字符串")
            return False
        
        if not isinstance(data['car_objects'], list):
            self.add_issue("字段类型错误", "car_objects 必须是数组")
            return False
        
        print(f"    ✓ 车系名称: {data['car_series_name']}")
        print(f"    ✓ 车型数量: {len(data['car_objects'])}")
        
        # 检查可选字段
        for field in optional_fields:
            if field in data:
                print(f"    ✓ {field}: {data[field]}")
        
        return True
    
    def validate_car_series_info(self, data):
        """验证车系信息的合理性"""
        print("  🚗 验证车系信息...")
        
        car_series_name = data.get('car_series_name', '')
        
        # 车系名称不应为空或过短
        if len(car_series_name) < 2:
            self.add_issue("车系名称异常", f"车系名称过短: {car_series_name}")
            return False
        
        # 检查目录ID格式（如果存在）
        catalog_id = data.get('catalog_id', '')
        if catalog_id:
            # 福特目录ID通常格式: WAEGB-CGE-2022-FocusMCAGBR202450
            if not re.match(r'^[A-Z0-9\-a-zA-Z]+$', catalog_id):
                self.add_issue("目录ID格式异常", f"目录ID格式不符合预期: {catalog_id}")
        
        # 检查车系代码格式（如果存在）
        series_code = data.get('series_code', '')
        if series_code:
            # 车系代码通常格式: ACMAA_VS-D3
            if not re.match(r'^[A-Z0-9_\-]+$', series_code):
                self.add_issue("车系代码格式异常", f"车系代码格式不符合预期: {series_code}")
        
        print("    ✓ 车系信息验证通过")
        return True
    
    def validate_car_objects(self, car_objects):
        """验证车型对象列表"""
        print(f"  🚙 验证 {len(car_objects)} 个车型对象...")
        
        if len(car_objects) == 0:
            self.add_issue("车型数据缺失", "未找到任何车型对象")
            return False
        
        for i, car_obj in enumerate(car_objects, 1):
            print(f"    验证车型 {i}: {car_obj.get('model_name', 'Unknown')}")
            
            if not self.validate_single_car_object(car_obj, i):
                return False
        
        # 验证车型唯一性
        if not self.validate_car_uniqueness(car_objects):
            return False
        
        print("    ✓ 所有车型对象验证通过")
        return True
    
    def validate_single_car_object(self, car_obj, index):
        """验证单个车型对象"""
        # 必需字段检查
        required_fields = ['model_name', 'price', 'drive']
        for field in required_fields:
            if field not in car_obj or not car_obj[field]:
                self.add_issue("车型字段缺失", f"车型 {index} 缺少必需字段: {field}")
                return False
        
        # 价格格式验证
        price = car_obj.get('price', '')
        if not re.match(r'^£[\d,]+$', price):
            self.add_issue("价格格式异常", f"车型 {index} 价格格式不正确: {price}")
            return False
        
        # Drive信息验证
        drive = car_obj.get('drive', '')
        if len(drive) < 10:  # Drive信息通常比较长
            self.add_issue("Drive信息异常", f"车型 {index} Drive信息过短: {drive}")
            return False
        
        # 配置数据验证
        config_fields = {
            'drive_types': '驱动类型',
            'body_styles': '车身样式', 
            'colors': '颜色选项',
            'interiors': '内饰选项',
            'extras': '选装件',
            'key_features': '主要特性'
        }
        
        stats = {}
        for field, desc in config_fields.items():
            count = len(car_obj.get(field, []))
            stats[desc] = count
            
            if count == 0:
                self.add_issue("配置数据缺失", f"车型 {index} 缺少 {desc}")
        
        print(f"      配置统计: {', '.join([f'{k}:{v}' for k,v in stats.items()])}")
        
        # 验证extras结构
        if not self.validate_extras_structure(car_obj.get('extras', []), index):
            return False
        
        return True
    
    def validate_extras_structure(self, extras, car_index):
        """验证选装件结构"""
        if not extras:
            return True  # 空列表是可接受的
        
        for i, extra in enumerate(extras):
            if not isinstance(extra, dict):
                self.add_issue("选装件结构错误", f"车型 {car_index} 选装件 {i} 不是字典类型")
                return False
            
            if 'Extra_name' not in extra or 'price' not in extra:
                self.add_issue("选装件字段缺失", f"车型 {car_index} 选装件 {i} 缺少必需字段")
                return False
        
        return True
    
    def validate_car_uniqueness(self, car_objects):
        """验证车型唯一性（model_name + drive组合应该唯一）"""
        print("    🔍 验证车型唯一性...")
        
        seen_combinations = set()
        
        for car_obj in car_objects:
            model_name = car_obj.get('model_name', '')
            drive = car_obj.get('drive', '')
            combination = f"{model_name}_{drive}"
            
            if combination in seen_combinations:
                self.add_issue("车型重复", f"发现重复的车型组合: {model_name} + {drive}")
                return False
            
            seen_combinations.add(combination)
        
        print(f"      ✓ {len(seen_combinations)} 个车型组合，无重复")
        return True
    
    def validate_business_logic_consistency(self, data):
        """验证业务逻辑一致性"""
        print("  🧠 验证业务逻辑一致性...")
        
        car_objects = data.get('car_objects', [])
        
        # 验证Drive和body_styles的关联性
        for car_obj in car_objects:
            drive = car_obj.get('drive', '')
            body_styles = car_obj.get('body_styles', [])
            
            # 检查body_styles是否与drive关联
            associated_drives = set()
            for style in body_styles:
                if isinstance(style, dict) and 'associated_drive' in style:
                    associated_drives.add(style['associated_drive'])
            
            if associated_drives and drive not in associated_drives:
                self.add_issue("Drive关联不一致", 
                             f"车型 {car_obj.get('model_name')} 的body_styles未正确关联到drive: {drive}")
        
        print("    ✓ 业务逻辑一致性验证通过")
        return True
    
    def add_issue(self, category, description):
        """添加问题记录"""
        self.issues_found.append({
            'category': category,
            'description': description
        })
    
    def generate_report(self):
        """生成验证报告"""
        print("\n" + "=" * 60)
        print("📊 数据完整性验证报告")
        print("=" * 60)
        
        if not self.issues_found:
            print("🎉 验证通过：未发现数据完整性问题")
            return True
        
        print(f"⚠️  发现 {len(self.issues_found)} 个问题:")
        
        # 按类别分组问题
        issues_by_category = {}
        for issue in self.issues_found:
            category = issue['category']
            if category not in issues_by_category:
                issues_by_category[category] = []
            issues_by_category[category].append(issue['description'])
        
        for category, descriptions in issues_by_category.items():
            print(f"\n❌ {category} ({len(descriptions)} 个问题):")
            for desc in descriptions:
                print(f"   - {desc}")
        
        return False


def main():
    """主函数"""
    print("🎯 福特配置器数据完整性验证")
    print("=" * 50)
    
    validator = DataIntegrityValidator()
    
    # 验证主输出文件
    output_file = './release/output.json'
    
    success = True
    
    # 基本结构验证
    if validator.validate_output_file(output_file):
        print("✅ 基本结构验证通过")
        
        # 业务逻辑验证
        with open(output_file, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        if validator.validate_business_logic_consistency(data):
            print("✅ 业务逻辑验证通过")
        else:
            success = False
    else:
        success = False
    
    # 生成最终报告
    final_result = validator.generate_report()
    
    if final_result and success:
        print("\n🎉 所有数据完整性验证通过！")
        return True
    else:
        print("\n⚠️  数据完整性验证发现问题，需要修复。")
        return False


if __name__ == "__main__":
    main()